/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package edu.uoc.tfc.exuoc.vistes;

import edu.uoc.tfc.exuoc.controladors.AbstractInGestor;
import edu.uoc.tfc.exuoc.controladors.InterfaceGestor;
import edu.uoc.tfc.exuoc.controladors.GestorCerques;
import edu.uoc.tfc.exuoc.controladors.GestorItems;
import edu.uoc.tfc.exuoc.controladors.GestorContenidors;
import edu.uoc.tfc.exuoc.errors.BuitException;
import edu.uoc.tfc.exuoc.errors.LlistatDAOException;

import edu.uoc.tfc.exuoc.utils.Eines;
import edu.uoc.tfc.exuoc.config.Config;
import edu.uoc.tfc.exuoc.model.Item;
import edu.uoc.tfc.exuoc.model.Contenidor;
import edu.uoc.tfc.exuoc.utils.seguretat.InjeccioCodi;
import edu.uoc.tfc.exuoc.consultes.ItemLlistat;
import edu.uoc.tfc.exuoc.consultes.ContenidorLlistat;


import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.ActionSupport;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;

import org.hibernate.HibernateException;

/**
 *
 * @author emoreno
 */
public class IGestorCerques extends AbstractInGestor
                    implements  ModelDriven<Item>{
        //extends ActionSupport implements Preparable , ModelDriven<Item> {

    private GestorCerques gc;
    
    private Item item=null;
    private Contenidor contenidor=null;

    private List<ItemLlistat>       llistaIt = new ArrayList<ItemLlistat>();
    private List<ContenidorLlistat>  llistaCon= new ArrayList<ContenidorLlistat>();

     //Identificador de sessió
    //private String idSessio="";

    private int quants=Config.valorNullInt;
    private int itemsPerPagina=Config.ITEM_PAGE+2;
    private int contenidorsPerPagina=Config.CONTENIDOR_PAGE+2;
    private int pos=0;

    //Valor de cerca
    private String cerca=Config.valorNullStr;
    
    //llista de les formes de cerca pels ítems
    private Map<String,String> formesCerca = new HashMap<String,String>();
    //Valor declarat de la form de cerca
    private String forma=Config.valorNullStr;

    //Inversió de la cerca
    private boolean invers=false;

    private String cadenaNula=Config.valorNullStr;


    public IGestorCerques(){
      //  this.openGestor();
        }

  
     private void openGestor(){

        if (this.gc==null)
            gc=new GestorCerques();
    }

     private void closeGestor(){
        if (this.gc!=null){
            gc.tancar();
            gc=null;}
    }

    //En tancar la classe es tanquen les connexions creades
    @Override
    protected void finalize() throws Throwable {

        try {

        } catch(Exception e) {
            this.getLog().info("Error tancant la classe Gestora Cerques. "+e.getMessage());
        }finally {
            super.finalize();
            this.closeGestor();
        }
    }



    @Override
    public Item getModel() {        return item;    }

    @Override
    public void prepare() {
        //Actualitzem la data de la sessió per l'usuari i assignem a idSessio
        //la sessió que li correspon.
        super.prepare();
    }

    public Item getItem() {        return item;    }

    public void setItem(Item item) {        this.item = item;    }

    public Contenidor getContenidor() {        return contenidor;    }

    public void setContenidor(Contenidor _contenidor) { this.contenidor = _contenidor;    }
  
/*    public GestorLogs getLogexuoc() {        return logexuoc;    }

    public void setLogexuoc(GestorLogs logexuoc) {        this.logexuoc = logexuoc;    }

    private void activarLog(){
        if (this.logexuoc==null) this.setLogexuoc(
                GestorLogs.getLogger(this.getClass().getName()));    }
*/
    public int getQuants() {        return quants;    }

    public void setQuants(int quants) {        this.quants = quants;    }

    public int getItemsPerPagina() {        return itemsPerPagina;    }

    public void setItemsPerPagina(int itemsPerPagina) { this.itemsPerPagina = itemsPerPagina;    }

    public int getContenidorsPerPagina() {        return contenidorsPerPagina;    }

    public void setContenidorsPerPagina(int contenidorsPerPagina) {
        this.contenidorsPerPagina = contenidorsPerPagina;    }

    public int getPos() {        return pos;    }

    public void setPos(int pos) {        this.pos = pos;    }

    public List<ItemLlistat> getLlistaIt() {        return llistaIt;    }

    public void setLlistaIt(List<ItemLlistat> llistaIt) {
        this.llistaIt = llistaIt;    }

    public void setLlistaCon(List<ContenidorLlistat> _llistaCon) {
        this.llistaCon = _llistaCon;    }

    public List<ContenidorLlistat> getLlistaCon() {        return llistaCon;    }

    public String getCerca() {        return cerca;    }

    public void setCerca(String cerca) {        this.cerca = cerca;    }

    public String getCadenaNula() {        return cadenaNula;    }

    public void setCadenaNula(String cadenaNula) {this.cadenaNula = cadenaNula;}

    public String getForma() {        return forma;    }

    public void setForma(String forma) {        this.forma = forma;    }

    public Map<String,String> getFormesCerca() {
        formesCerca.put("autor","Autor");
        formesCerca.put("datapub","Data anterior a:");
        formesCerca.put("nom","Nom ítem");
        formesCerca.put("tipus","Tipus");
        
        return formesCerca;
    }

    public void setFormesCerca(Map<String,String> formesCerca) {
        this.formesCerca = formesCerca;    }

    public boolean isInvers() {        return invers;    }

    public void setInvers(boolean invers) {        this.invers = invers;    }





    //Crida per defecte
    @Override
    public String execute() {        return SUCCESS;    }


    public String items(){
        this.cerca();
        return "cerca";
    }

    /**
     * Mètode per fer les cerques per nom de contenidors
     * @return
     */
    public String contenidors(){
        this.openGestor();
        String stat=ActionSupport.INPUT;
        this.setQuants(Config.valorNullInt);
        this.setLlistaCon(null);

        try {
            //No hi ha cap nom a buscar
            if (this.getCerca()==null || this.getCerca().isEmpty()
                    || (this.getCerca().equals(Config.valorNullStr)) ){
                GestorContenidors gCon= GestorContenidors.getInstance();

                this.setQuants(gCon.num());
                if (!comprovarLimits(this.getPos(),0,this.getQuants())) {
                    this.addActionError("Límits de posició fora de rang");
                    return ActionSupport.ERROR;
                }

                List<ContenidorLlistat> llistaC = new ArrayList<ContenidorLlistat>();
                Iterator<Contenidor> it=null;
                it=gCon.llistat(this.getPos(), this.getPos() + this.getContenidorsPerPagina());

                //nombre de contenidors totals

                while (it.hasNext()){
                    Contenidor c=(Contenidor)it.next();
                    llistaC.add(new ContenidorLlistat(c.getId(),c.getNom(),c.getDatapub(),c.getItems().size()));
                }
                this.setLlistaCon(llistaC);
                if (gCon!=null) gCon.tancar();

            //Tenim un valor per cercar, en aquest cas es busca només pel camp nom
            }else{
                this.setLlistaCon(
                    (List<ContenidorLlistat>)this.omplirLlista(
                        Contenidor.class,"nom",this.getCerca(),this.getPos(),
                        this.getPos()+this.getContenidorsPerPagina()));

                //Es busca el nombre de contenidors que cumpleixen la condició
                //ja que pel mètode omplir només es coneix el valor per la paginació
                this.setQuants(this.quantsPerNom(Contenidor.class, this.getCerca()));
            }

        }catch (LlistatDAOException ex) {
            this.getLog().error("llista buida. Classe :Contenidors. {}",ex.getLocalizedMessage());

        }catch (NullPointerException ex) {
            this.getLog().error("llista buida. {}",ex.getLocalizedMessage());

        }catch (BuitException ex){
            this.getLog().error("llista buida de contenidors. {}",ex.getLocalizedMessage());
        }
        this.closeGestor();
        return stat;
    }


    public void llistaContenidors(){
        Iterator<Contenidor> ll;
        List<ContenidorLlistat> llistaC=new ArrayList<ContenidorLlistat>();

        try {
            GestorContenidors gCon = GestorContenidors.getInstance();
            //Obtenir la llista dde contenidors
            ll=gCon.llistatContenidors();
            while (ll.hasNext()){
                Contenidor co=(Contenidor)ll.next();

                llistaC.add(new ContenidorLlistat(co.getId(),co.getNom(),co.getDatapub(),Config.valorNullInt));
            }
            //S'emplena la llista llistaCon de contenidors
            this.setLlistaCon(llistaC);
            ll=null;

            gCon.tancar();

        }catch(NullPointerException e){
            this.getLog().error("IGC:llistaContenidors:Error obtenint la llista"
                    +" de contenidors. {}",e.getLocalizedMessage());
        }catch(LlistatDAOException e){
            this.getLog().error("llistaContenidors:Error d`accés a la llista de "
                    +"contenidors. {}",e.getLocalizedMessage());
        }

    }

    public String cerca(){
        String stat=ActionSupport.INPUT;
        int quantitat=Config.valorNullInt;
        this.setQuants(Config.valorNullInt);
        this.setLlistaIt(null);
        InterfaceGestor gestor=null;
        try{
            //S'emplena la llista de contenidors per poder afegir ítems
            this.llistaContenidors();

            if (this.getCerca()==null || this.getCerca().isEmpty()
                    || (this.getCerca().equals(Config.valorNullStr)) ){
                 gestor= GestorItems.getInstance();
                 //nombre de contenidors totals
                 this.setQuants(gestor.num());
                 if (!comprovarLimits(this.getPos(),0,this.getQuants())) {
                    this.addActionError("Límits de posició fora de rang");
                    return ActionSupport.ERROR;
                 }
                 List<ItemLlistat> llistaI = new ArrayList<ItemLlistat>();
                 Iterator<Item> it=null;
                 it=(Iterator<Item>)gestor.llistat(this.getPos(), this.getPos()
                         + this.getItemsPerPagina());
                 
                 //nombre de contenidors totals
                //this.setQuants(gestor.num());
                while (it.hasNext()){
                    Item i=(Item)it.next();
                    llistaI.add(new ItemLlistat(i.getId(),i.getNom(),
                            i.getDatapub(),i.getAutor(),i.getVisites(),
                            i.getArxiu().getTipus(),i.getContenidor().getNom(),
                            i.getPrivat()));
                }
                 this.setLlistaIt(llistaI);
                if (gestor!=null) gestor.tancar();
            }else{
                //Ep tenim un valor de cerca
                this.setLlistaIt(
                    (List<ItemLlistat>)this.omplirLlista( 
                    Item.class,this.getForma(),this.getCerca(),this.getPos(),
                            this.getPos()+this.getItemsPerPagina()));

                //Es busca el nombre de contenidors que cumpleixen la condició
                //ja que pel mètode omplir només es coneix el valor per la paginació


                quantitat=this.quantsPerForma(this.getForma(), this.getCerca(),false);
                this.setQuants(quantitat);
            }

        }catch (NullPointerException ex) {
            this.getLog().error("llista d`ítems buida. {}",ex.getLocalizedMessage());
            if (gestor!=null) gestor.tancar();
            gestor=null;

        }catch (LlistatDAOException ex) {
            this.getLog().error("Error obtenint la llista d`ítems buida. {}",ex.getLocalizedMessage());
            if (gestor!=null) gestor.tancar();
            gestor=null;

        }catch (BuitException ex){
            this.getLog().error("llista buida d`ítems. {}",ex.getLocalizedMessage());
            if (gestor!=null) gestor.tancar();
            gestor=null;
        }



        this.closeGestor();
        return stat;
    }


    private int quants(Class obj){
        int num=Config.valorNullInt;
        String classeNom=obj.getSimpleName();
     
        try {

            InterfaceGestor gestor=null;
            if ( classeNom.equals(Contenidor.class.getSimpleName()))
                gestor = GestorContenidors.getInstance();
            else 
                gestor = GestorItems.getInstance();

            num = gestor.num();
            gestor.tancar();

        } catch (HibernateException ex) {
            String[] llista ={obj.getSimpleName(),ex.getLocalizedMessage()};
            this.getLog().error("no s'ha pogut obtenir el nombre d'elements ,Classe :{}. {}",llista);

        }catch(BuitException e){
            this.getLog().error("llista buida. Classe :"+obj.getSimpleName(),e.getLocalizedMessage());
        }

        return num;

    }

    private int quantsPerNom(Class obj,String valor){
        int num=Config.valorNullInt;
        String classeNom=obj.getSimpleName();

        try {

            InterfaceGestor gestor=null;
            if ( classeNom.equals(Contenidor.class.getSimpleName()))
                gestor = GestorContenidors.getInstance();
            else
                gestor = GestorItems.getInstance();

            num = gestor.num(valor);

            gestor.tancar();

        } catch (HibernateException ex) {
            String[] llista ={obj.getSimpleName(),ex.getLocalizedMessage()};
            this.getLog().error("no s'ha pogut obtenir el nombre d'elements ,Classe :{}. {}",llista);

        }catch(BuitException e){
            this.getLog().error("llista buida. Classe :"+obj.getSimpleName(),e.getLocalizedMessage());
        }catch(NullPointerException e){
            this.getLog().error("Algun valor null. Classe.");
        }

        return num;

    }

    /**
     * Es calcula el nombre d'ítems del tipus forma indicat segons la cerca de
     * valor
     * @param tipusCerca
     * @param valor
     * @return
     */

    private int quantsPerForma(String tipusCerca, String valor,boolean invertir){
        int num=Config.valorNullInt;
       
        try {            
            GestorItems gestor=GestorItems.getInstance();

            num = gestor.num(tipusCerca, valor);

            gestor.tancar();

        } catch (HibernateException ex) {
            String[] llista ={tipusCerca,ex.getLocalizedMessage()};
            this.getLog().error("no s'ha pogut obtenir el nombre d'elements ,forma:{}. {}",llista);

        }catch(BuitException e){
            this.getLog().error("llista buida. forma :"+tipusCerca,e.getLocalizedMessage());
            
        }catch(NullPointerException e){
            this.getLog().error("Algun valor null.");
        }

        return num;

    }


    private List<?> omplirLlista(Class classe,String camp,String valor, int ini, int fi){

        //Iterator <Contenidor> ll=null;
        Iterator <?> ll=null;
        
        //List<ContenidorLlistat> llistaC = new ArrayList<ContenidorLlistat>();
        List llistaEnti=null ;
        //this.getLogexuoc().info("Control de salt 1");
        InjeccioCodi filtre = new InjeccioCodi();

        //GestorContenidors gCon=new GestorContenidors();
        InterfaceGestor gestor=null;
        try {
            if (ini < 0) ini=0;
             String nomClasse=classe.getSimpleName();
            //ll=gCon.llistat("nom", filtre.netejar(nomContenidor), ini, fi);
            if (nomClasse.equals(Contenidor.class.getSimpleName())){
                gestor=GestorContenidors.getInstance();
                llistaEnti=new ArrayList<ContenidorLlistat>();
                //this.getLogexuoc().info("Control de salt 2");
            }
            else if(nomClasse.equals(Item.class.getSimpleName())){
                gestor=GestorItems.getInstance();
                llistaEnti=new ArrayList<ItemLlistat>();
                //this.getLogexuoc().info("Control de salt 3");
            }

             Eines.escriu(camp+":"+valor);
            ll=gestor.llistat(filtre.netejar(camp), filtre.netejar(valor), ini, fi);

            while (ll.hasNext()){
               //this.getLogexuoc().info("Control de salt 4");
               if(nomClasse.equals(Contenidor.class.getSimpleName())){
                    Contenidor c=(Contenidor)ll.next();
                    //this.llistaCon.add(new ContenidorLlistat(c.getId(),c.getNom(),c.getDataPub(),c.getItems().size()));
                    //08-1-11 ContenidorLlistat cl =new ContenidorLlistat(c.getId(),c.getNom(),c.getDataPub(),c.getItems().size());
                    llistaEnti.add(new ContenidorLlistat(c.getId(),c.getNom(),c.getDatapub(),c.getItems().size()));

                }else if(nomClasse.equals(Item.class.getSimpleName())){
                    //this.getLogexuoc().info("Control de salt 5");
                    Item i=(Item)ll.next();
                    llistaEnti.add(new ItemLlistat(i.getId(),i.getNom(),
                            i.getDatapub(),i.getAutor(),i.getVisites(),
                            i.getArxiu().getTipus(),i.getContenidor().getNom(),
                            i.getPrivat()));
                }
            }
        }catch (LlistatDAOException ex) {
                this.getLog().error("Error: Llistat. ",ex.getLocalizedMessage());

        }catch (IndexOutOfBoundsException ex) {
                this.getLog().error("IGC:OmplirLlista: llista de contenidors es "
                        +"troba fora de rang."+ex.getMessage());
        }catch (NullPointerException ex) {
                this.getLog().error("IGC:OmplirLlista: llista de contenidors nul.la."
                        +ex.getMessage());
        }catch (BuitException ex) {
                this.getLog().error("IGC:OmplirLlista: llista de contenidors buida."
                        +ex.getMessage());
        }
        //this.getLogexuoc().info("Control de salt 6");
        if (gestor==null) gestor.tancar();
        ll=null;
        return llistaEnti;
    }


    public static void main (String args[]){
        IGestorCerques igc = new IGestorCerques();
       // Eines.escriu("Quants: "+igc.quants(Item.class));
       // Eines.escriu("Quants per nom: "+igc.quantsPerNom(Contenidor.class,"con"));
        
       
        //Iterator<ItemLlistat> it=(Iterator<ItemLlistat>) igc.omplirLlista(Item.class, "nom", "pro", 0, 15).iterator();
        //igc.contenidors();
        //Iterator<ContenidorLlistat> ic=igc.getLlistaCon().iterator();
/*        while (it.hasNext()){
            ItemLlistat c =it.next();
            Eines.escriu(c.getNom());
        }*/


        GestorItems gi = GestorItems.getInstance();
       // Eines.escriu("Quants :"+igc.quantsPerForma("tipus", "jpg", false));
        Iterator<Item> it=null;
        try {
                it = gi.llistat("autor", "emili", 0, 20);

                while (it.hasNext()){
                    Eines.escriu(  ((Item)it.next()).getNom() );
                }
        } catch (LlistatDAOException ex) {
            gi.getLog().info("Error Llistat. "+ex.getMessage());
        }
        
    

       

        igc.closeGestor();
    }
    
}
